<!DOCTYPE html>
<html lang="en">
    <head>
        <title>three.js webgl - loaders - Draco loader</title>
        <meta charset="utf-8" />
        <meta
            name="viewport"
            content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0" />
        <link
            type="text/css"
            rel="stylesheet"
            href="../../three.js/examples/main.css" />
    </head>

    <body>
        <div id="container"></div>
        <div id="info">
            <a
                href="https://threejs.org"
                target="_blank"
                rel="noopener"
                >three.js</a
            >
            -
            <a
                href="https://github.com/google/draco"
                target="_blank"
                rel="noopener"
                >DRACO</a
            >
            loader
        </div>

        <script type="importmap">
            {
                "imports": {
                    "three": "../../three.js/build/three.module.js",
                    "three/addons/": "../../three.js/examples/jsm/"
                }
            }
        </script>

        <script type="module">
            import * as THREE from "three";

            import { DRACOLoader } from "three/addons/loaders/DRACOLoader.js";
            import { OrbitControls } from "three/addons/controls/OrbitControls.js";

            let camera, scene, renderer, controls;

            const container = document.querySelector("#container");

            // Configure and create Draco decoder.
            const dracoLoader = new DRACOLoader();
            dracoLoader.setDecoderPath("../../three.js/examples/jsm/libs/draco/");
            dracoLoader.setDecoderConfig({ type: "js" });

            init();

            function init() {
                camera = new THREE.PerspectiveCamera(35, window.innerWidth / window.innerHeight, 0.1, 15);

                scene = new THREE.Scene();
                scene.background = new THREE.Color(0x443333);
                scene.fog = new THREE.Fog(0x443333, 1, 4);

                // Ground
                // const plane = new THREE.Mesh(
                //     new THREE.PlaneGeometry(8, 8),
                //     new THREE.MeshPhongMaterial({ color: 0xcbcbcb, specular: 0x101010 })
                // );
                // plane.rotation.x = -Math.PI / 2;
                // plane.position.y = 0.03;
                // plane.receiveShadow = true;
                // scene.add(plane);

                // Lights
                const hemiLight = new THREE.HemisphereLight(0x8d7c7c, 0x494966, 3);
                scene.add(hemiLight);

                const spotLight = new THREE.SpotLight();
                spotLight.intensity = 7;
                spotLight.angle = Math.PI / 16;
                spotLight.penumbra = 0.5;
                spotLight.castShadow = true;
                spotLight.position.set(-1, 1, 1);
                scene.add(spotLight);

                const material = new THREE.ShaderMaterial({
                    uniforms: {
                        // lightPosition: { value: new THREE.Vector3(0.000001,0.000001,1) },
                        lightPosition: { value: camera.position },
                    },
                    vertexShader: `
                        varying vec2 vUv;
                        varying vec3 Normal;

                        void main() {
                            vUv = uv;
                            vec4 modelViewPosition = modelViewMatrix * vec4(position, 1.0);
                            gl_Position = projectionMatrix * modelViewPosition;
                            Normal =  normalize(normal);

                        }`,
                    fragmentShader: `
                        uniform vec3 lightPosition;
                        varying vec3 Normal;

                        void main() {
                                
                            vec3 color = vec3(1.);
                            float intensity = abs( dot(normalize(lightPosition),Normal) );

                            if( abs( intensity ) < 0.5) {
                                gl_FragColor = vec4(vec3(1), 1.0);
                            } else {
                                // gl_FragColor = vec4(vec3(0), 1.0);
                                discard;
                                // gl_FragColor = vec4(vec3(1), 1.0);
                            }
                        }`,
                });

                // const mesh = new THREE.Mesh(new THREE.BoxGeometry(0.1, 0.1, 0.1), material);
                // const mesh = new THREE.Mesh(new THREE.SphereGeometry( 0.0015, 32, 16 ), material);
                const mesh = new THREE.Mesh(new THREE.TorusKnotGeometry( 0.02, 0.006, 100, 16 ), material);

                // mesh.position.set(-0.085, 0.14, 0.02);
                mesh.position.set(0.1, 0.1, 0.);

                scene.add(mesh);

                dracoLoader.load("../../three.js/examples/models/draco/bunny.drc", function (geometry) {
                    geometry.computeVertexNormals();

                    // const material = new THREE.MeshStandardMaterial({ color: 0xa5a5a5 });

                    const mesh = new THREE.Mesh(geometry, material);
                    // mesh.castShadow = true;
                    // mesh.receiveShadow = true;
                    scene.add(mesh);

                    // Release decoder resources.
                    dracoLoader.dispose();
                });

                // renderer
                renderer = new THREE.WebGLRenderer({ antialias: true });
                renderer.setPixelRatio(window.devicePixelRatio);
                renderer.setSize(window.innerWidth, window.innerHeight);
                renderer.setAnimationLoop(animate);
                renderer.shadowMap.enabled = true;
                container.appendChild(renderer.domElement);

                controls = new OrbitControls(camera, renderer.domElement);

                controls.target.set(0, 0.1, 0);
                controls.object.position.set(0, 0.1, 0.5);

                window.controls = controls;

                window.addEventListener("resize", onWindowResize);
            }

            function onWindowResize() {
                camera.aspect = window.innerWidth / window.innerHeight;
                camera.updateProjectionMatrix();

                renderer.setSize(window.innerWidth, window.innerHeight);
            }

            function animate() {
                const timer = Date.now() * 0.0003;

                // camera.position.x = -0.5;
                // camera.position.z = 0.5;
                // camera.lookAt(0, 0.1, 0);

                renderer.render(scene, camera);
            }
        </script>
    </body>
</html>
